<template>
  <div
    class="mask fixed left-0 top-0 w-screen h-screen z-99"
    @contextmenu.prevent="removeContextmenu()"
    @mousedown="removeContextmenu()"
  ></div>
  <div
    class="contextmenu fixed select-none z-999"
    :style="{
      left: style.left + 'px',
      top: style.top + 'px',
    }"
    @contextmenu.prevent
  >
    <menu-content
      :menus="menus"
      :handle-click-menu-item="handleClickMenuItem"
    />
  </div>
</template>

<script setup lang="ts">
import { Axis, ContextmenuItem } from './types';
import MenuContent from './MenuContent.vue';
const props = defineProps<{
  axis: Axis;
  el: HTMLElement;
  menus: ContextmenuItem[];
  removeContextmenu: Function;
}>();

const style = computed(() => {
  const MENU_WIDTH = 170;
  const MENU_HEIGHT = 30;
  const DIVIDER_HEIGHT = 11;
  const PADDING = 5;

  const { x, y } = props.axis;
  const menuCount = props.menus.filter(
    (menu) => !(menu.divider || menu.hide)
  ).length;
  const dividerCount = props.menus.filter((menu) => menu.divider).length;

  const menuWidth = MENU_WIDTH;
  const menuHeight =
    menuCount * MENU_HEIGHT + dividerCount * DIVIDER_HEIGHT + PADDING * 2;

  const screenWidth = document.body.clientWidth;
  const screenHeight = document.body.clientHeight;

  return {
    left: screenWidth <= x + menuWidth ? x - menuWidth : x,
    top: screenHeight <= y + menuHeight ? y - menuHeight : y,
  };
});

const handleClickMenuItem = (item: ContextmenuItem, event: MouseEvent) => {
  if (item.disable) return;
  if (item.children && !item.handler) return;
  if (item.handler) item.handler(props.el, event);
  props.removeContextmenu();
};
</script>

<style scoped></style>
